package com.helsinki.controller;

import com.helsinki.pojo.SysLog;
import com.helsinki.service.SysLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;

@Component // 注册对象
@Aspect // 通知类
public class SysLogAspects {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SysLogService sysLogService;

    /*
    private Date visitTime; // 访问时间
    private String username; // 操作的用户
    private String ip; // 登录IP
    private String url; // 访问的资源地址 /product/findById
    private Long executionTime; // 操作所用时间
    private String method; // 真正执行的方法(类名+方法名)
     */
    // 定义切入点表达式
    @Pointcut("execution(* com.helsinki.controller.*.*(..))")
    public void pc() {
    }

    private Date visitTime;

    // 前置通知
    @Before("pc()")
    public void before() {
        // 1.访问时间
        visitTime = new Date();
    }

    // 后置通知
    @After("pc()")
    public void after(JoinPoint jp) {
        // 2.获得用户名
        // HttpSession session = request.getSession();
        // session.getAttribute("SPRING_SECURITY_CONTEXT");
        SecurityContext securityContext = SecurityContextHolder.getContext();
        User user = (User) securityContext.getAuthentication().getPrincipal();
        String username = user.getUsername();
        // 3.ip
        String ip = request.getRemoteAddr();
        // 4.url
        String url = request.getRequestURI();
        // 5.执行时长
        long executionTime = new Date().getTime() - visitTime.getTime();
        // 6.访问方法
        // 6.1 获得正在执行的处理器类
        Class target = jp.getTarget().getClass();
        if (!(target == SyslogController.class)) { // 排除掉SyslogController
            String className = target.getName();
            // 6.2 获得正在执行的方法名
            String methodName = jp.getSignature().getName();
            String method = "[类名:]" + className + ",[方法名:]" + methodName;
            // 7.封装对象
            SysLog sysLog = new SysLog();
            sysLog.setVisitTime(visitTime);
            sysLog.setIp(ip);
            sysLog.setUsername(username);
            sysLog.setUrl(url);
            sysLog.setExecutionTime(executionTime);
            sysLog.setMethod(method);
            sysLog.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            // 8.调用service完成存储
            sysLogService.addLog(sysLog);
        }
    }
}